import pandas as pd
# Laden der Daten und erste Informationen
daten = pd.read_csv('california_housing_DE.csv')
daten.info()
# Check der Vollständigkeit
print(daten.isnull().sum())
# Inhalt der ersten 10 Zeilen
daten.head(10)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Laenge 20640 non-null float64
1 Breite 20640 non-null float64
2 Alter 20640 non-null float64
3 Zimmer 20640 non-null float64
4 Schlafzimmer 20433 non-null float64
5 Bevoelkerung 20640 non-null float64
6 Haushalte 20640 non-null float64
7 Einkommen 20640 non-null float64
8 Hauswert 20640 non-null float64
9 Kuestennaehe 20640 non-null object
dtypes: float64(9), object(1)
memory usage: 1.6+ MB
Laenge 0
Breite 0
Alter 0
Zimmer 0
Schlafzimmer 207
Bevoelkerung 0
Haushalte 0
Einkommen 0
Hauswert 0
Kuestennaehe 0
dtype: int64
| Laenge | Breite | Alter | Zimmer | Schlafzimmer | Bevoelkerung | Haushalte | Einkommen | Hauswert | Kuestennaehe | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | -122.23 | 37.88 | 41.0 | 880.0 | 129.0 | 322.0 | 126.0 | 8.3252 | 452600.0 | nahe_Bucht |
| 1 | -122.22 | 37.86 | 21.0 | 7099.0 | 1106.0 | 2401.0 | 1138.0 | 8.3014 | 358500.0 | nahe_Bucht |
| 2 | -122.24 | 37.85 | 52.0 | 1467.0 | 190.0 | 496.0 | 177.0 | 7.2574 | 352100.0 | nahe_Bucht |
| 3 | -122.25 | 37.85 | 52.0 | 1274.0 | 235.0 | 558.0 | 219.0 | 5.6431 | 341300.0 | nahe_Bucht |
| 4 | -122.25 | 37.85 | 52.0 | 1627.0 | 280.0 | 565.0 | 259.0 | 3.8462 | 342200.0 | nahe_Bucht |
| 5 | -122.25 | 37.85 | 52.0 | 919.0 | 213.0 | 413.0 | 193.0 | 4.0368 | 269700.0 | nahe_Bucht |
| 6 | -122.25 | 37.84 | 52.0 | 2535.0 | 489.0 | 1094.0 | 514.0 | 3.6591 | 299200.0 | nahe_Bucht |
| 7 | -122.25 | 37.84 | 52.0 | 3104.0 | 687.0 | 1157.0 | 647.0 | 3.1200 | 241400.0 | nahe_Bucht |
| 8 | -122.26 | 37.84 | 42.0 | 2555.0 | 665.0 | 1206.0 | 595.0 | 2.0804 | 226700.0 | nahe_Bucht |
| 9 | -122.25 | 37.84 | 52.0 | 3549.0 | 707.0 | 1551.0 | 714.0 | 3.6912 | 261100.0 | nahe_Bucht |
daten.describe()
| Laenge | Breite | Alter | Zimmer | Schlafzimmer | Bevoelkerung | Haushalte | Einkommen | Hauswert | |
|---|---|---|---|---|---|---|---|---|---|
| count | 20640.000000 | 20640.000000 | 20640.000000 | 20640.000000 | 20433.000000 | 20640.000000 | 20640.000000 | 20640.000000 | 20640.000000 |
| mean | -119.569704 | 35.631861 | 28.639486 | 2635.763081 | 537.870553 | 1425.476744 | 499.539680 | 3.870671 | 206855.816909 |
| std | 2.003532 | 2.135952 | 12.585558 | 2181.615252 | 421.385070 | 1132.462122 | 382.329753 | 1.899822 | 115395.615874 |
| min | -124.350000 | 32.540000 | 1.000000 | 2.000000 | 1.000000 | 3.000000 | 1.000000 | 0.499900 | 14999.000000 |
| 25% | -121.800000 | 33.930000 | 18.000000 | 1447.750000 | 296.000000 | 787.000000 | 280.000000 | 2.563400 | 119600.000000 |
| 50% | -118.490000 | 34.260000 | 29.000000 | 2127.000000 | 435.000000 | 1166.000000 | 409.000000 | 3.534800 | 179700.000000 |
| 75% | -118.010000 | 37.710000 | 37.000000 | 3148.000000 | 647.000000 | 1725.000000 | 605.000000 | 4.743250 | 264725.000000 |
| max | -114.310000 | 41.950000 | 52.000000 | 39320.000000 | 6445.000000 | 35682.000000 | 6082.000000 | 15.000100 | 500001.000000 |
import plotly.express as px
# Laenge, Breite wird weggelassen, da die Positionen weniger gut statistisch
# interpretiert werden kann; Hauswert wird gesondert untersucht, da es die
# Zielgröße ist
fig = px.box(daten.loc[:, 'Alter':'Einkommen'],
labels={'variable': 'Merkmal', 'value': 'Wert'})
fig.show()
# Statistik für alle Merkmale und Zielgröße
daten.describe()
| Laenge | Breite | Alter | Zimmer | Schlafzimmer | Bevoelkerung | Haushalte | Einkommen | Hauswert | |
|---|---|---|---|---|---|---|---|---|---|
| count | 20640.000000 | 20640.000000 | 20640.000000 | 20640.000000 | 20433.000000 | 20640.000000 | 20640.000000 | 20640.000000 | 20640.000000 |
| mean | -119.569704 | 35.631861 | 28.639486 | 2635.763081 | 537.870553 | 1425.476744 | 499.539680 | 3.870671 | 206855.816909 |
| std | 2.003532 | 2.135952 | 12.585558 | 2181.615252 | 421.385070 | 1132.462122 | 382.329753 | 1.899822 | 115395.615874 |
| min | -124.350000 | 32.540000 | 1.000000 | 2.000000 | 1.000000 | 3.000000 | 1.000000 | 0.499900 | 14999.000000 |
| 25% | -121.800000 | 33.930000 | 18.000000 | 1447.750000 | 296.000000 | 787.000000 | 280.000000 | 2.563400 | 119600.000000 |
| 50% | -118.490000 | 34.260000 | 29.000000 | 2127.000000 | 435.000000 | 1166.000000 | 409.000000 | 3.534800 | 179700.000000 |
| 75% | -118.010000 | 37.710000 | 37.000000 | 3148.000000 | 647.000000 | 1725.000000 | 605.000000 | 4.743250 | 264725.000000 |
| max | -114.310000 | 41.950000 | 52.000000 | 39320.000000 | 6445.000000 | 35682.000000 | 6082.000000 | 15.000100 | 500001.000000 |
# Median berechnen
median_schlafzimmer =daten['Schlafzimmer'].mean()
print(f'Median Schlafzimmer: {median_schlafzimmer:.1f} ')
# fehlende Werte erzetzen
daten['Schlafzimmer'] = daten['Schlafzimmer'].fillna(median_schlafzimmer)
# Überprüfen, ob keine fehlenden Werte mehr vorhanden sind
print(f'Fehlende Werte nach Imputation: {daten['Schlafzimmer'].isna().sum()} ')
Median Schlafzimmer: 537.9
Fehlende Werte nach Imputation: 0
import plotly.express as px
fig = px.histogram(daten, x='Hauswert',
nbins=50,
title='Verteilung der Hauswerte')
fig.update_layout(
yaxis_title='Anzahl',
xaxis_title='Hauswert (USD)'
)
fig.show()
haeufigkeiten = daten['Kuestennaehe'].value_counts()
print(haeufigkeiten)
fig = px.bar(x=haeufigkeiten.index, y=haeufigkeiten.values,
labels={'x': 'Küstennähe', 'y': 'Anzahl'},
title='Verteilung der Kuestennähe-Kategorien')
fig.show()
Kuestennaehe
weniger_als_1h_zum_Ozean 9136
Binnenland 6551
nahe_Ozean 2658
nahe_Bucht 2290
Insel 5
Name: count, dtype: int64
numerische_daten = daten.loc[:, 'Laenge' : 'Hauswert']
korrelation = numerische_daten.corr()
fig = px.imshow(korrelation,
text_auto='.2f',
aspect='auto',
labels={'color': 'Korrelation'},
title='Korrelationsmatrix')
fig.show()
fig = px.scatter(daten,
x='Laenge',
y='Breite',
color='Hauswert',
labels={'Laenge': 'Längengrad',
'Breite': 'Breitengrad',
'Hauswert': 'Hauswert (USD)'},
title='Geografische Verteilung der Hauspreise',
opacity=0.5
)
fig.show()
daten['Zimmer_pro_Haushalt'] = daten['Zimmer'] / daten['Haushalte']
daten['Schlafzimmer_Anteil'] = daten['Schlafzimmer'] / daten['Zimmer']
daten['Personen_pro_Haushalt'] = daten['Bevoelkerung'] / daten['Haushalte']
#neue_merkmale = ['Zimmer_pro_Haushalt', 'Schlafzimmer_Anteil', 'Personen_pro_Haushalt']
neue_daten = daten.loc[:, ['Zimmer_pro_Haushalt', 'Schlafzimmer_Anteil', 'Personen_pro_Haushalt', 'Hauswert' ]]
neue_korrelationen = neue_daten.corr()
print(neue_korrelationen)
fig = px.imshow(neue_korrelationen,
text_auto='.2f',
aspect='auto',
labels={'color': 'Korrelation'},
title='Neue Korrelationsmatrix')
fig.show()
Zimmer_pro_Haushalt Schlafzimmer_Anteil \
Zimmer_pro_Haushalt 1.000000 -0.347501
Schlafzimmer_Anteil -0.347501 1.000000
Personen_pro_Haushalt -0.004852 0.002373
Hauswert 0.151948 -0.220049
Personen_pro_Haushalt Hauswert
Zimmer_pro_Haushalt -0.004852 0.151948
Schlafzimmer_Anteil 0.002373 -0.220049
Personen_pro_Haushalt 1.000000 -0.023737
Hauswert -0.023737 1.000000
daten = pd.get_dummies(data=daten, columns=['Kuestennaehe'])
daten.head()
| Laenge | Breite | Alter | Zimmer | Schlafzimmer | Bevoelkerung | Haushalte | Einkommen | Hauswert | Zimmer_pro_Haushalt | Schlafzimmer_Anteil | Personen_pro_Haushalt | Kuestennaehe_Binnenland | Kuestennaehe_Insel | Kuestennaehe_nahe_Bucht | Kuestennaehe_nahe_Ozean | Kuestennaehe_weniger_als_1h_zum_Ozean | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | -122.23 | 37.88 | 41.0 | 880.0 | 129.0 | 322.0 | 126.0 | 8.3252 | 452600.0 | 6.984127 | 0.146591 | 2.555556 | False | False | True | False | False |
| 1 | -122.22 | 37.86 | 21.0 | 7099.0 | 1106.0 | 2401.0 | 1138.0 | 8.3014 | 358500.0 | 6.238137 | 0.155797 | 2.109842 | False | False | True | False | False |
| 2 | -122.24 | 37.85 | 52.0 | 1467.0 | 190.0 | 496.0 | 177.0 | 7.2574 | 352100.0 | 8.288136 | 0.129516 | 2.802260 | False | False | True | False | False |
| 3 | -122.25 | 37.85 | 52.0 | 1274.0 | 235.0 | 558.0 | 219.0 | 5.6431 | 341300.0 | 5.817352 | 0.184458 | 2.547945 | False | False | True | False | False |
| 4 | -122.25 | 37.85 | 52.0 | 1627.0 | 280.0 | 565.0 | 259.0 | 3.8462 | 342200.0 | 6.281853 | 0.172096 | 2.181467 | False | False | True | False | False |
from sklearn.model_selection import train_test_split
X = daten.drop('Hauswert', axis=1)
y = daten['Hauswert']
# Train-Test-Split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(f'Trainingsdaten: {X_train.shape[0]} Datenpunkte')
print(f'Testdaten: {X_test.shape[0]} Datenpunkte')
print(f'Anzahl Merkmale: {X_train.shape[1]}')
Trainingsdaten: 16512 Datenpunkte
Testdaten: 4128 Datenpunkte
Anzahl Merkmale: 16
from sklearn.tree import DecisionTreeRegressor
modell_baum = DecisionTreeRegressor(random_state=42)
modell_baum.fit(X_train, y_train)
r2_train_baum = modell_baum.score(X_train, y_train)
r2_test_baum = modell_baum.score(X_test, y_test)
print(f'R²-Score Entscheidungsbaum (Training): {r2_train_baum:.2f}')
print(f'R²-Score Entscheidungsbaum (Test): {r2_test_baum:.2f}')
R²-Score Entscheidungsbaum (Training): 1.00
R²-Score Entscheidungsbaum (Test): 0.60
from sklearn.ensemble import RandomForestRegressor
modell_rf = RandomForestRegressor(n_estimators=100, random_state=42)
modell_rf.fit(X_train, y_train)
r2_train_rf = modell_rf.score(X_train, y_train)
r2_test_rf = modell_rf.score(X_test, y_test)
print(f'R²-Score Random Forest (Training): {r2_train_rf:.2f}')
print(f'R²-Score Random Forest (Test): {r2_test_rf:.2f}')
R²-Score Random Forest (Training): 0.97
R²-Score Random Forest (Test): 0.81
# Feature Importance extrahieren
importance = pd.DataFrame({
'Merkmal': X_train.columns,
'Feature Importance': modell_rf.feature_importances_
}).sort_values('Feature Importance', ascending=False)
# Top 10 visualisieren
top10 = importance.head(10)
fig = px.bar(top10, x='Feature Importance', y='Merkmal', orientation='h',
title='Top 10 wichtigste Merkmale im Random Forest')
fig.update_yaxes(autorange="reversed")
fig.show()
print(top10)
Merkmal Feature Importance
7 Einkommen 0.481627
11 Kuestennaehe_Binnenland 0.137486
10 Personen_pro_Haushalt 0.121489
0 Laenge 0.057738
1 Breite 0.056273
2 Alter 0.044300
8 Zimmer_pro_Haushalt 0.025741
9 Schlafzimmer_Anteil 0.024239
3 Zimmer 0.012730
4 Schlafzimmer 0.012197
from sklearn.linear_model import LinearRegression
modell_lr = LinearRegression()
modell_lr.fit(X_train, y_train)
r2_train_lr = modell_lr.score(X_train, y_train)
r2_test_lr = modell_lr.score(X_test, y_test)
print(f'R²-Score lineare Regression (Training): {r2_train_lr:.2f}')
print(f'R²-Score lineare Regression (Test): {r2_test_lr:.2f}')
R²-Score lineare Regression (Training): 0.66
R²-Score lineare Regression (Test): 0.58